import React, {useCallback, useEffect, useMemo, useState} from "react"
import DataPageLayout from "../../components/DataPageLayout";
import {
    AutoComplete,
    Button,
    Col,
    ConfigProvider,
    Form,
    Input,
    InputNumber,
    message,
    Popover,
    Row,
    Select,
    Space,
    theme,
    Typography,
    Upload
} from "antd";
import {
    DeleteOutlined,
    EditOutlined, InfoCircleFilled,
    MinusCircleOutlined,
    PlusOutlined,
    QuestionCircleOutlined,
    UploadOutlined
} from "@ant-design/icons";
import AuthorizationResource from "../../components/AuthorizationResource";
import FormDrawer from "../../components/FormDrawer";
import {
    addGoods,
    AddGoodsRequest, batchDisableGoods, batchEnableGoods, batchUpdateGoods,
    deleteGoods, disableGoods, downloadImportSubGoodsTemplate,
    downloadImportTemplate, EditSubGoodsRequest, enableGoods,
    exportGoodsToExcel,
    getAllGoodsUnits,
    getGoodsDetail,
    GoodsDetail,
    importGoodsFromExcel, importSubGoodsFromExcel,
    queryGoods,
    QueryGoodsResponse,
    updateGoods
} from "../../apis/GoodsApi";
import {Pageable} from "../../utils/Page";
import {buildDisableOrEnableColumnProps, mergePaginationAndPageable, sorterToSort} from "../../utils/AntdTableUtils";
import {NumberIdAndName, ProblemDetail} from "../../types/BasicModels";
import {getAllGoodsBrand} from "../../apis/GoodsBrandsApi";
import {getAllGoodsCategories} from "../../apis/GoodsCategoriesApi";
import {Response} from "@zxy-cn/fetcher"
import employeeAuthorizationStore from "../../store/EmployeeAuthorizationStore";
import {observerDashboardPageWrapper} from "./ObserverDashboardPageWrapper";
import {getAllFactory} from "../../apis/FactoriesApi";
import {saveTo} from "../../utils/FileSaver";
import LoadableButton from "../../components/LoadableButton";
import OnlinePaginationGoodsTable, {QueryGoodsTableDataCondition} from "../../components/OnlinePaginationGoodsTable";
import ArrayUtils from "@zxy-cn/array-utils";
import TableColumnSelectModal from "../TableColumnSelectModal";
import {ChronoUnit, Period, TemporalAmount} from "@js-joda/core";
import RefreshableSelectFormItem from "../RefreshableSelectFormItem";
import EditSubGoodsFormItem from "../EditSubGoodsFormItem";
import Paragraph from "antd/es/skeleton/Paragraph";
import GoodsWithSubGoodsSelector from "../GoodsWithSubGoodsSelector";
import {
    addCompositeGoods,
    CompositeGoodsDetail,
    getCompositeGoodsDetail,
    updateCompositeGoods
} from "../../apis/CompositeGoodsApi";
import GoodsQuantitySelector from "../GoodsQuantitySelector";


export interface GoodsProps {

}

export const periodUnits = [
    "年",
    "月",
    "天"
];

export type PeriodUnits = keyof { [I in (typeof periodUnits)[number]] }

export interface GoodsFormData {
    name: string
    price: number
    amount: number
    barcode: string
    brandId?: number
    categoryId?: number
    factoryId?: number
    boxSpecification?: string
    costPrice?: number
    units: Array<GoodsUnitFormData>
    registrationCertificateNumber?: string
    recordFilingNumber?: string
    expressionPeriodUnit?: PeriodUnits
    expressionPeriodValue?: number
    executeStandard?: string
    note?: string
    subGoodsList: Array<EditSubGoodsRequest>
}

interface GoodsUnitFormData {
    id?: number
    name: string
    basicMultiple: number
    updatable: boolean
}


interface CompositeGoodsFormData {
    id: number
    name: string
    price: number
    note?: string
    items: {
        id: number,
        subGoodsId?: number | null,
        quantity: number,
        name: string,
        barcode: string,
        subGoodsNumber?: string | null,
        subGoodsName?: string | null
    }[]
}

export type DisableCondition = ["0" | "1" | "-1"]

interface GoodsPageQueryGoodsTableDataCondition extends QueryGoodsTableDataCondition<QueryGoodsResponse> {
    disable?: DisableCondition
}

export function disableInConditionToDisableInRequest(disable: GoodsPageQueryGoodsTableDataCondition["disable"]) {
    switch (disable?.[0]) {
        case "1":
            return true
        case "0":
            return false
        case "-1":
            return undefined
        default:
            return undefined
    }
}

export function preHandleGoodsFormData(values: GoodsFormData): AddGoodsRequest {
    if (values.units && values.units.length === 1 && !values.units[0].name) {
        values.units = [];
    }
    const newValues: AddGoodsRequest = {
        ...values,
    }
    if (values.expressionPeriodValue && values.expressionPeriodUnit) {
        let period: Period;
        switch (values.expressionPeriodUnit) {
            case "天":
                period = Period.ofDays(values.expressionPeriodValue);
                break;
            case "月":
                period = Period.ofMonths(values.expressionPeriodValue);
                break;
            case "年":
                period = Period.ofYears(values.expressionPeriodValue);
                break;
            default:
                throw new Error("未知的保质期单位")
        }
        newValues.expressionPeriod = period.toString()
    }
    return newValues;
}

const GoodsPage: React.FC<GoodsProps> = () => {
    const [openAddGoodsDrawer, setOpenAddGoodsDrawer] = useState(false)
    const [openAddCompositeGoodsDrawer, setOpenAddCompositeGoodsDrawer] = useState(false)
    const [pageable, setPageable] = useState(new Pageable())
    const [data, setData] = useState<QueryGoodsResponse[]>([])


    const [loading, setLoading] = useState(false)
    const [totalElements, setTotalElements] = useState(0)


    const [editGoodsId, setEditingGoodsId] = useState<number>()
    const [editingGoodsDetail, setEditingGoodsDetail] = useState<GoodsDetail>()
    const editingGoodsExpressionPeriod = useMemo(() => {
        if (editingGoodsDetail?.expressionPeriod) {
            return Period.parse(editingGoodsDetail!.expressionPeriod!)
        } else {
            return undefined
        }

    }, [editingGoodsDetail?.expressionPeriod]);
    const editingGoodsExpressionPeriodUnitEnum = useMemo(() => {
        if (editingGoodsExpressionPeriod) {
            let temporalUnits = editingGoodsExpressionPeriod.units();
            for (let temporalUnit of temporalUnits) {
                if (editingGoodsExpressionPeriod.get(temporalUnit as ChronoUnit)) {
                    return temporalUnit
                }
            }
            return undefined
        } else {
            return undefined
        }
    }, [editingGoodsExpressionPeriod])
    const editingGoodsExpressionPeriodUnit = useMemo(() => {
        switch (editingGoodsExpressionPeriodUnitEnum) {
            case ChronoUnit.DAYS:
                return "天"
            case ChronoUnit.MONTHS:
                return "月"
            case ChronoUnit.YEARS:
                return "年"
            default:
                return undefined
        }
    }, [editingGoodsExpressionPeriodUnitEnum]);


    const editingGoodsExpressionPeriodValue = useMemo(() => {
        if (editingGoodsExpressionPeriod && editingGoodsExpressionPeriodUnitEnum) {
            return editingGoodsExpressionPeriod.get(editingGoodsExpressionPeriodUnitEnum)
        } else {
            return undefined
        }
    }, [editingGoodsExpressionPeriodUnitEnum, editingGoodsExpressionPeriodUnitEnum])
    useEffect(() => {
        if (editGoodsId) {
            getGoodsDetail(editGoodsId).then(res => {
                setEditingGoodsDetail(res.data)
            })
        } else {
            setEditingGoodsDetail(undefined)
        }
    }, [editGoodsId])

    const [editingCompositeGoodsId, setEditingCompositeGoodsId] = useState<number>()
    const [editingCompositeGoodsDetail, setEditingCompositeGoodsDetail] = useState<CompositeGoodsDetail>()

    useEffect(() => {
        if (editingCompositeGoodsId) {
            getCompositeGoodsDetail(editingCompositeGoodsId).then(response => {
                setEditingCompositeGoodsDetail(response)
            })
        } else {
            setEditingCompositeGoodsId(undefined)
        }
    }, [editingCompositeGoodsId]);


    const [brands, setBrands] = useState<NumberIdAndName[]>([])
    const [categories, setCategories] = useState<NumberIdAndName[]>([])
    const [goodsUnits, setGoodsUnits] = useState<string[]>([])

    async function queryGoodsBrands() {
        return getAllGoodsBrand().then(response => setBrands(response.data))
    }

    async function queryGoodsCategories() {
        return getAllGoodsCategories().then(response => setCategories(response.data))
    }

    useEffect(() => {
        // noinspection JSIgnoredPromiseFromCall
        queryGoodsBrands();
        // noinspection JSIgnoredPromiseFromCall
        queryGoodsCategories();
        getAllGoodsUnits().then(response => setGoodsUnits(response.data))
    }, [])


    const [barcodeFieldError, setBarcodeFieldError] = useState<string>()

    const existBarcode = barcodeFieldError === "EXIST_BARCODE"


    function buildBrandSelectFormItem(nameList?:string[]) {
        return <RefreshableSelectFormItem name={"brandId"} label={"品牌"}
                                          onRefresh={queryGoodsBrands}
                                          dependencies={["name","brandId"]}
                                          appendRender={form=>{
                                              let name = form.getFieldValue("name")?.toString();
                                              let brandId = form.getFieldValue("brandId");
                                              if ((!!name || !!nameList?.length) && !brandId){
                                                  let suggestBrands = brands.filter(b=>(!!name && name.toLowerCase().includes(b.name.toLowerCase())) || nameList?.every(it=>it.toLowerCase().includes(b.name.toLowerCase())));
                                                  if (suggestBrands.length>0){
                                                      return <Typography>
                                                          <Typography.Text type={"secondary"}>建议</Typography.Text>
                                                          {suggestBrands.map((i,index)=>{
                                                              return <React.Fragment key={i.id}>
                                                                  {index!==0 && <Typography.Text type={"secondary"}>、</Typography.Text>}
                                                                  <Typography.Link onClick={()=>{
                                                                      form.setFieldValue("brandId",i.id)
                                                                  }}>{i.name}</Typography.Link>
                                                              </React.Fragment>
                                                          })}
                                                      </Typography>
                                                  }
                                              }
                                              return <></>
                                          }}
                                          builder={refreshing => <Select<NumberIdAndName>
                                              style={{minWidth: 200}}
                                              placeholder={"选择品牌"}
                                              showSearch
                                              loading={refreshing}
                                              filterOption={(input: string, option?) => {
                                                  return (option?.children as unknown as string).toLowerCase().includes(input.toLowerCase());
                                              }}>
                                              {brands.map(brand => {
                                                  return <Select.Option key={brand.id}
                                                                        value={brand.id}>{brand.name}</Select.Option>
                                              })}
                                          </Select>}/>;
    }

    function buildGoodsCategorySelectFormItem() {
        return <RefreshableSelectFormItem name={"categoryId"} label={"分类"}
                                          onRefresh={queryGoodsCategories}
                                          builder={refreshing => <Select placeholder={"选择分类"}
                                                                         style={{minWidth: 200}}
                                                                         loading={refreshing}
                                                                         showSearch
                                                                         filterOption={(input: string, option?) => {
                                                                             return (option?.children as unknown as string).toLowerCase().includes(input.toLowerCase());
                                                                         }}>
                                              {categories.map(category => {
                                                  return <Select.Option key={category.id}
                                                                        value={category.id}>{category.name}</Select.Option>
                                              })}
                                          </Select>}/>;
    }

    function buildBoxSpecificationFormItem() {
        return <Form.Item label={"箱规"} name={"boxSpecification"}>
            <Input/>
        </Form.Item>;
    }

    function buildExpressionPeriodFormItem() {
        return <Space>
            <Form.Item<GoodsFormData> label={"保质期"} name={"expressionPeriodValue"}>
                <Input type={"number"} min={1}/>
            </Form.Item>
            <Form.Item<GoodsFormData> name={"expressionPeriodUnit"} label={" "}>
                <Select placeholder={"单位"} style={{minWidth: 84}}
                        options={[...periodUnits,].map(value => {
                            return {
                                label: value,
                                value: value,
                            }
                        })}/>
            </Form.Item>
        </Space>;
    }


    function buildCostPriceFormItem() {
        return employeeAuthorizationStore.hasAuthority("货品_进价_修改") && <Col span={12}>
            <Form.Item label={"进价"} name="costPrice" rules={[]}>
                <Input type={"number"}/>
            </Form.Item>
        </Col>;
    }

    function buildFormItems() {
        return <>
            <Form.Item label={"名称"} name="name" rules={[{required: true}]}>
                <Input/>
            </Form.Item>
            <Form.Item label={"条码"} name="barcode" rules={[{required: true}]}
                       hasFeedback={existBarcode}
                       help={existBarcode ? "条码已存在" : undefined}
                       validateStatus={existBarcode ? "error" : undefined}>
                <Input type={"number"}/>
            </Form.Item>
            <Row gutter={16}>
                <Col span={12}>
                    <Form.Item label={"零售价"} name="price" rules={[{required: true}]}>
                        <Input type={"number"}/>
                    </Form.Item>
                </Col>
                {
                    buildCostPriceFormItem()
                }

                <Col span={24}>
                    <EditSubGoodsFormItem create={!editGoodsId}/>
                </Col>

                <Col span={12}>
                    {<Form.Item label={"库存"} name="amount"
                                rules={[{required: true}, {type: "number", min: !editGoodsId ? 0 : undefined}]}>
                        <InputNumber/>
                    </Form.Item>}
                </Col>
                <Col span={12}>
                    {buildBrandSelectFormItem()}
                </Col>
                <Col span={12}>
                    {buildGoodsCategorySelectFormItem()}
                </Col>
                <Col span={12}>
                    {buildBoxSpecificationFormItem()}
                </Col>
                <Col span={12}>
                    {buildExpressionPeriodFormItem()}
                </Col>
                <Col span={24}>
                    <EditGoodsUnitFormItem initialValue={editingGoodsDetail?.units} goodsUnits={goodsUnits}/>
                </Col>
                <Col span={12}>
                    <Form.Item<AddGoodsRequest> label={"生产证编号"} name={"registrationCertificateNumber"}
                                                rules={[{max: 50}]}>
                        <Input/>
                    </Form.Item>
                </Col>
                <Col span={12}>
                    <Form.Item<AddGoodsRequest> label={"备案编号"} name={"recordFilingNumber"} rules={[{max: 50}]}>
                        <Input/>
                    </Form.Item>
                </Col>
                <Col span={12}>
                    <Form.Item<AddGoodsRequest> label={"执行标准"} name={"executiveStandard"} rules={[{max: 50}]}>
                        <Input/>
                    </Form.Item>
                </Col>
                <Col span={12}>
                    <Form.Item<AddGoodsRequest> label={"备注"} name={"note"}>
                        <Input/>
                    </Form.Item>
                </Col>
            </Row>
        </>
    }

    function buildCompositeGoodsFormItems() {
        return <>
            <Form.Item label={"名称"} name={"name"} rules={[]}>
                <Input/>
            </Form.Item>
            <Form.Item label={"零售价"} name="price" rules={[{required: true}]}>
                <Input type={"number"}/>
            </Form.Item>
            <Form.Item label={"组合的商品"} name={"items"}>
                <GoodsQuantitySelector/>
            </Form.Item>
            <Form.Item label={"备注"} name={"note"}>
                <Input/>
            </Form.Item>
        </>
    }

    const [condition, setCondition] = useState<GoodsPageQueryGoodsTableDataCondition>({disable: ["0"]})
    const [disable, setDisable] = useState<boolean | undefined>(false)
    const query = useCallback(async () => {
        let pageable = condition?.pagination ? mergePaginationAndPageable(condition.pagination, new Pageable(), condition.sorter) : new Pageable();
        setPageable(pageable)
        setLoading(true)
        try {
            const response = await queryGoods(condition ? {
                name: condition?.name,
                barcode: condition?.barcode,
                brandIds: condition?.brandIds,
                categoryIds: condition?.categoryIds,
                factoryIds: condition?.factoryIds,
                disable: disableInConditionToDisableInRequest(condition.disable),
            } : {}, pageable);
            setTotalElements(response.data.totalElements);
            setData(response.data.content);
            setSelectedRowKeys([])
        } finally {
            setLoading(false);
        }
    }, [condition, disable])

    useEffect(() => {
        query()
    }, [query]);
    const [importing, setImporting] = useState(false)


    const [messageApi, contextHolder] = message.useMessage();


    const [openExportColumnSelectModal, setOpenExportColumnSelectModal] = useState(false)

    const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([])
    const [batchUpdateDrawerVisible, setBatchUpdateDrawerVisible] = useState(false)

    const batchEnableButtonDisable = useMemo(() => {
        return selectedRowKeys.length === 0 || !data.filter(item => selectedRowKeys.includes(item.id)).some(it => it.disable)
    }, [selectedRowKeys, data]);

    const batchDisableButtonDisable = useMemo(() => {
        return selectedRowKeys.length === 0 || !data.filter(item => selectedRowKeys.includes(item.id)).some(it => !it.disable)
    }, [selectedRowKeys, data]);
    return (
        <>
            {contextHolder}
            <DataPageLayout leftActions={<>
                <TableColumnSelectModal
                    availableColumns={["名称", "条码", "品牌", "类别", "厂商", "库存", "零售价", "箱规"]}
                    open={openExportColumnSelectModal} onConfirm={async fields => {
                    let response = await exportGoodsToExcel(condition ? {
                        ...condition,
                        disable: disableInConditionToDisableInRequest(condition.disable),
                        fields
                    } : {fields}, condition ? sorterToSort(condition.sorter) : undefined);
                    saveTo(response.data, "货品.xlsx")
                    setOpenExportColumnSelectModal(false)
                }} cacheKey={"goods"} onCancel={_ => setOpenExportColumnSelectModal(false)}/>
                <LoadableButton onClick={async () => {
                    setOpenExportColumnSelectModal(true)
                }}>导出</LoadableButton></>} rightActions={<>
                {employeeAuthorizationStore.hasAuthority("货品_导入") ?
                    <Space size={4}><Upload fileList={[]}
                                            accept={"application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}
                                            maxCount={1}
                                            beforeUpload={file => {
                                                setImporting(true)
                                                importGoodsFromExcel(file).then(response => {
                                                    if (response.data) {
                                                        query();
                                                        return messageApi.success(`成功导入${response.data}个货品`);
                                                    } else {
                                                        return messageApi.error(`无货品被导入，请检查格式是否正确`);
                                                    }
                                                }).finally(() => {
                                                    setImporting(false)
                                                });
                                                return false
                                            }}>
                        <Button icon={<UploadOutlined/>} loading={importing}>导入</Button>
                    </Upload>
                        <Popover title={"导入货品"} content={
                            <Typography>
                                <Typography.Paragraph>
                                    按照约定的格式上传excel文件。
                                    <Typography.Link onClick={() => {
                                        downloadImportTemplate().then(res => res.data)
                                            .then(blob => {
                                                saveTo(blob, "导入商品模板.xlsx")
                                            })

                                    }}>下载模板</Typography.Link>
                                </Typography.Paragraph>
                                <Typography.Paragraph>
                                    <ul>
                                        <li>商品的品牌、厂商、分类等数据如果不存在则会新建</li>
                                        <li>相同的条码会被忽略</li>
                                        <li>必填的属性未填会被忽略</li>
                                    </ul>
                                </Typography.Paragraph>
                            </Typography>
                        }><QuestionCircleOutlined/></Popover>
                    </Space> : undefined}
                    <AuthorizationResource authorities={["货品_新增"]}>
                        <Button type={"primary"} onClick={() => {
                            setOpenAddGoodsDrawer(true)
                        }}><PlusOutlined/>新增货品</Button>
                    </AuthorizationResource>
                    <AuthorizationResource authorities={["货品_新增"]}>
                        <Button type={"primary"} onClick={() => {
                            setOpenAddCompositeGoodsDrawer(true)
                        }}><PlusOutlined/>新增组合品</Button>
                    </AuthorizationResource>
                    {employeeAuthorizationStore.hasAuthority("货品_导入") ?
                        <Space size={4}><Upload fileList={[]}
                                                accept={"application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}
                                                maxCount={1}
                                                beforeUpload={file => {
                                                    setImporting(true)
                                                    importSubGoodsFromExcel(file).then(response => {
                                                        if (response.data) {
                                                            // query();
                                                            return messageApi.success(`成功导入${response.data}个子商品`);
                                                        } else {
                                                            return messageApi.error(`无货品被导入，请检查格式是否正确`);
                                                        }
                                                    }).finally(() => {
                                                        setImporting(false)
                                                    });
                                                    return false
                                                }}>
                            <Button icon={<UploadOutlined/>} loading={importing}>导入子商品</Button>
                        </Upload>
                            <Popover title={"导入子商品"} content={
                                <Typography>
                                    <Typography.Paragraph>
                                        按照约定的格式上传excel文件。
                                        <Typography.Link onClick={() => {
                                            downloadImportSubGoodsTemplate().then(res => res.data)
                                                .then(blob => {
                                                    saveTo(blob, "导入商品模板.xlsx")
                                                })

                                        }}>下载模板</Typography.Link>
                                    </Typography.Paragraph>
                                    <Typography.Paragraph>
                                        <ul>
                                            <li>子商品对应条码的商品必须先被创建</li>
                                            <li>相同条码和编号的子商品会被忽略</li>
                                            <li>必填的属性未填会被忽略</li>
                                        </ul>
                                    </Typography.Paragraph>
                                </Typography>
                            }><QuestionCircleOutlined/></Popover>
                            <AuthorizationResource authorities={["货品_修改"]}>
                                <Space>
                                    <Button icon={<EditOutlined/>} onClick={() => {
                                        setBatchUpdateDrawerVisible(true)
                                    }} disabled={!selectedRowKeys.length}>批量修改</Button>
                                    <LoadableButton onClick={async () => {
                                        await batchEnableGoods(selectedRowKeys)
                                        setSelectedRowKeys([])
                                        await query()
                                    }} disabled={batchEnableButtonDisable}>批量启用</LoadableButton>

                                    <LoadableButton onClick={async () => {
                                        await batchDisableGoods(selectedRowKeys)
                                        setSelectedRowKeys([])
                                        await query()
                                    }} disabled={batchDisableButtonDisable}>批量禁用</LoadableButton>
                                </Space>
                            </AuthorizationResource>

                        </Space> : undefined}
            </>
            }>

                <ConfigProvider componentSize={"small"}>
                    <OnlinePaginationGoodsTable<QueryGoodsResponse> onConditionChange={(condition, _, filters,) => {
                        setCondition({...condition, disable: filters.disable as any,})
                    }} data={data}
                                                                    rowSelection={{
                                                                        selectedRowKeys,
                                                                        onChange: (_, rows) => {
                                                                            setSelectedRowKeys(rows.map(it => it.id))
                                                                        },
                                                                        onCell:(data, index)=> {
                                                                            // 整个cell 点击后都会触发选择
                                                                            return {
                                                                                onClick:(event)=> {
                                                                                    event.stopPropagation()
                                                                                    if (selectedRowKeys.includes(data.id)){
                                                                                        ArrayUtils.remove(selectedRowKeys,data.id)
                                                                                    }else {
                                                                                        selectedRowKeys.push(data.id)
                                                                                    }
                                                                                    setSelectedRowKeys(Array.from(selectedRowKeys))
                                                                                }
                                                                            }
                                                                        }
                                                                    }}
                                                                    customColumns={columns => {
                                                                        if (employeeAuthorizationStore.hasAnyAuthority("货品_修改", "货品_删除")) {
                                                                            columns.push(buildDisableOrEnableColumnProps(condition.disable))
                                                                            columns.push({
                                                                                ignoreInExcel: true,
                                                                                title: "操作",
                                                                                fixed: "right",
                                                                                render: (_, item) => {
                                                                                    return <Space>
                                                                                        {employeeAuthorizationStore.hasAuthority("货品_修改") &&
                                                                                            <Button type={"link"}
                                                                                                    onClick={(event) => {
                                                                                                        event.stopPropagation()

                                                                                                        if (item.compositeGoodsAmount) {
                                                                                                            setEditingCompositeGoodsId(item.id)
                                                                                                        } else {
                                                                                                            setEditingGoodsId(item.id)
                                                                                                        }
                                                                                                    }}>
                                                                                                <EditOutlined/>
                                                                                            </Button>}
                                                                                        {employeeAuthorizationStore.hasAuthority("货品_删除") &&
                                                                                            <><LoadableButton
                                                                                                type={"link"}
                                                                                                danger
                                                                                                onClick={async (event) => {
                                                                                                    event.stopPropagation()
                                                                                                    await deleteGoods(item.id);
                                                                                                    await query()
                                                                                                }}>
                                                                                                <DeleteOutlined/>
                                                                                            </LoadableButton>
                                                                                                <LoadableButton
                                                                                                    type={"link"}
                                                                                                    danger={!item.disable}
                                                                                                    onClick={async (event) => {
                                                                                                        event.stopPropagation()
                                                                                                        item.disable ? await enableGoods(item.id) : await disableGoods(item.id)
                                                                                                        await query()
                                                                                                    }}>{item.disable ? "启用" : "禁用"}</LoadableButton>
                                                                                            </>}
                                                                                    </Space>
                                                                                }
                                                                            })


                                                                        }

                                                                        employeeAuthorizationStore.hasAuthority("货品_进价_查看") && ArrayUtils.insertAfter(columns, value => value.dataIndex === "price", {
                                                                            dataIndex: "costPrice",
                                                                            title: "进价"
                                                                        })
                                                                        return columns
                                                                    }}
                                                                    pagination={{
                                                                        current: pageable.page,
                                                                        pageSize: pageable.size,
                                                                        total: totalElements,
                                                                        showQuickJumper:true,
                                                                    }}
                                                                    loading={loading}/>
                </ConfigProvider>
            </DataPageLayout>
            <FormDrawer<GoodsFormData> onClose={() => {
                setBatchUpdateDrawerVisible(false)
            }}
                                       title={"批量修改"}
                                       onConfirm={async (values) => {
                                           const data = preHandleGoodsFormData(values)
                                           return batchUpdateGoods({...data, goodsIds: selectedRowKeys}).then(() => {
                                               setBatchUpdateDrawerVisible(false)
                                               query()
                                           })
                                       }}
                                       open={batchUpdateDrawerVisible}>
                <Typography>
                    <Typography.Paragraph>
                        <blockquote>填写需要批量修改的属性，没有可不填</blockquote>
                    </Typography.Paragraph>
                </Typography>
                <Form.Item label={"零售价"} name="price">
                    <Input type={"number"}/>
                </Form.Item>
                {buildCostPriceFormItem()}
                {buildBrandSelectFormItem(selectedRowKeys.map(value => data.find(g=>g.id===value)?.name??""))}
                {buildGoodsCategorySelectFormItem()}
                {buildBoxSpecificationFormItem()}
                {buildExpressionPeriodFormItem()}
                {<Form.Item label={"库存"} name="amount"
                            rules={[{type: "number", min: !editGoodsId ? 0 : undefined}]}>
                    <InputNumber/>
                </Form.Item>}
            </FormDrawer>
            <FormDrawer<GoodsFormData> onClose={() => {
                setBarcodeFieldError(undefined)
                setOpenAddGoodsDrawer(false);
            }} onBeforeConfirm={() => setBarcodeFieldError(undefined)}
                                       title={"新增货品"}
                                       onConfirm={async (values) => {
                                           const data = preHandleGoodsFormData(values)
                                           return addGoods(data).then(() => {
                                               setOpenAddGoodsDrawer(false)
                                               query()
                                           }).catch((response: Response<ProblemDetail>) => {
                                               if (response.status === 400) {
                                                   setBarcodeFieldError(response.data.detail)
                                               }
                                           })
                                       }}
                                       open={openAddGoodsDrawer}>
                {buildFormItems()}
            </FormDrawer>

            <FormDrawer<GoodsFormData> open={!!editingGoodsDetail} title={"修改商品"} onClose={() => {
                setEditingGoodsId(undefined)
            }} onConfirm={async (values) => {
                const data = preHandleGoodsFormData(values)
                return updateGoods(editGoodsId!!, data).then(() => {
                    query()
                    setEditingGoodsId(undefined)
                })
            }} initialValues={editingGoodsDetail ? {
                ...editingGoodsDetail,
                brandId: editingGoodsDetail.brand?.id,
                categoryId: editingGoodsDetail.category?.id,
                factoryId: editingGoodsDetail.factory?.id,
                expressionPeriodUnit: editingGoodsExpressionPeriodUnit ?? "年",
                expressionPeriodValue: editingGoodsExpressionPeriodValue
            } : undefined}>
                {buildFormItems()}
            </FormDrawer>

            <FormDrawer onClose={() => {
                setOpenAddCompositeGoodsDrawer(false);
            }}
                        title={"新增组合品"}
                        onConfirm={async (values) => {

                            return addCompositeGoods({
                                ...values, items: values.items.map(item => {
                                    return {
                                        goodsId: item.id,
                                        subGoodsId: item.subGoodsId,
                                        amount: item.quantity
                                    }
                                })
                            }).then(() => {
                                setOpenAddCompositeGoodsDrawer(false)
                                query()
                            })
                        }}
                        open={openAddCompositeGoodsDrawer}>
                {buildCompositeGoodsFormItems()}
            </FormDrawer>

            <FormDrawer<CompositeGoodsFormData> onClose={() => {
                setEditingCompositeGoodsId(undefined)
            }}
                                                initialValues={editingCompositeGoodsDetail ? {
                                                    id: editingCompositeGoodsDetail.id,
                                                    name: editingCompositeGoodsDetail.name,
                                                    price: editingCompositeGoodsDetail.price,
                                                    note: editingCompositeGoodsDetail?.note,
                                                    items: editingCompositeGoodsDetail?.items.map(item => ({
                                                        id: item.goodsId,
                                                        subGoodsId: item.subGoodsId,
                                                        quantity: item.amount,
                                                        name: item.name,
                                                        barcode: item.barcode,
                                                        subGoodsNumber: item.subGoodsNumber,
                                                        subGoodsName: item.subGoodsName
                                                    })) ?? []
                                                } : undefined}
                                                title={"修改组合品"}
                                                onConfirm={async (values) => {

                                                    return updateCompositeGoods(editingCompositeGoodsId!!, {
                                                        ...values, items: values.items.map(item => {
                                                            return {
                                                                goodsId: item.id,
                                                                subGoodsId: item.subGoodsId,
                                                                amount: item.quantity
                                                            }
                                                        })
                                                    }).then(() => {
                                                        setEditingCompositeGoodsId(undefined)
                                                        query()
                                                    })
                                                }}
                                                open={!!editingCompositeGoodsId}>
                {buildCompositeGoodsFormItems()}
            </FormDrawer>
        </>
    )
}

export interface EditGoodsUnitFormItemProps {
    initialValue?: Array<GoodsUnitFormData>
    goodsUnits: string[]
}

const EditGoodsUnitFormItem: React.FC<EditGoodsUnitFormItemProps> = ({initialValue, goodsUnits}) => {
    const [basicUnit, setBasicUnit] = useState<string>()
    useEffect(() => {
        setBasicUnit(initialValue?.[0]?.name)
    }, [initialValue]);
    const [updatableStateMap, setUpdatableStateMap] = useState<(boolean | undefined)[]>(initialValue ? initialValue.map(value => value.updatable) : []);
    let {token} = theme.useToken();

    return <Form.List name={"units"}>
        {(fields, {add, remove}) => {
            return <>
                <Form.Item label={"单位"} name={[0, "name"]}>
                    <Input onChange={(event) => {
                        setBasicUnit(event.currentTarget.value)
                    }} value={basicUnit} style={{maxWidth: 180}} placeholder="基本单位"/>
                </Form.Item>
                {fields.length > 1 && fields.slice(1).map((field, index) => {
                    let updatable = updatableStateMap[index + 1] !== false;
                    return <Space key={field.key} align={"baseline"}>
                        <Form.Item name={[field.name, "name"]} required={true}
                                   rules={[{required: true, message: "请输入单位"}, {type: "string", min: 1}]}>
                            <AutoComplete options={goodsUnits.filter(value => value !== basicUnit).map(value => ({
                                value,
                                label: value
                            }))}>
                                <Input readOnly={!updatable}/>
                            </AutoComplete>
                        </Form.Item>
                        <>=</>
                        <Form.Item name={[field.name, "basicMultiple"]} required={true}
                                   rules={[{required: true, message: "请输入换算系数"}, {type: "number", min: 1}]}>
                            <InputNumber type={"number"} readOnly={!updatable}/>
                        </Form.Item>
                        <>{basicUnit}</>
                        <MinusCircleOutlined onClick={() => {
                            let array = Array.from(updatableStateMap);
                            array.splice(index + 1, 1)
                            setUpdatableStateMap(array)
                            remove(field.name);
                        }}/>
                    </Space>
                })}

                {fields.length > 1 && <Form.Item>
                    <span
                        style={{color: token.colorTextSecondary}}>注：辅助单位在被其他主要功能引用后，将无法修改名称和换算</span>
                </Form.Item>}
                {!!basicUnit && <Form.Item>
                    <Button type="dashed" onClick={() => {
                        updatableStateMap[updatableStateMap.length] = true;
                        add();
                    }} block icon={<PlusOutlined/>}>
                        添加辅助单位
                    </Button>
                </Form.Item>}
            </>
        }}
    </Form.List>
}


export default observerDashboardPageWrapper(GoodsPage, "goods", "货品")
